import axios from 'axios'
import store from '@/store'

import { customHistory } from './history'
// import { logout } from '@/store/actions'
// import { message } from 'antd'
import { Toast } from 'antd-mobile'
import { setToken, clearToken, isAuth } from '.'

const http = axios.create({
  // baseURL: 'http://geek.itheima.net/v1_0'
  baseURL: 'http://toutiao.itheima.net/v1_0',
})

// 请求拦截器
http.interceptors.request.use((config) => {
  // 获取token
  const {
    login: { token },
  } = store.getState()

  // 除了登录请求外，其他请求统一添加 token
  if (token) {
    config.headers!.Authorization = `Bearer ${token}`
  }

  return config
})

http.interceptors.response.use(
  (res) => {
    // 简化返回数据
    return res.data
  },
  async (error) => {
    // == 无感刷新token=》401 start ==
    if (error.response.status === 401) {
      // Toast.show({
      //   content: '登录超时，请重新登录',
      //   duration: 1000,
      //   afterClose: () => {
      //     customHistory.push('/login', {
      //       from: customHistory.location.pathname,
      //     })
      //     // 触发退出 action，将 token 等清除
      //     // store.dispatch(logout())
      //   },
      // })
      // 无感刷新token
      // 在此处，通过 refresh_token 来换取新的 token
      try {
        // 1. 没有登录过
        if (!isAuth()) {
          console.log('not login')
          // 手动抛出异常
          throw new Error(error)
        }
        // 2. 登陆过：用 refresh_token 换取新的 token
        const { refresh_token } = store.getState().login
        // 注意：
        //  1-这里使用axios单独发请求，需要完整地址
        //  2-对于 put 请求来来说，第 3 个参数才表示配置项，才能够设置 请求头
        //  3-此处的请求头用的是 refresh_token 而不是 token
        const res = await axios.put(
          `http://toutiao.itheima.net/v1_0/authorizations`,
          null,
          {
            headers: {
              Authorization: `Bearer ${refresh_token}`,
            },
          }
        )

        // console.log(res)
        // 使用新拿到的 token 替换本地的 token 以及 redux 中的 token
        // 组装所有 token
        const tokens = {
          // token 是最新的，接口返回的
          token: res.data.data.token,
          // 因为接口没有返回新的 refresh_token，所以，需要使用原来的
          refresh_token,
        }
        setToken(tokens)
        store.dispatch({ type: 'login/token', payload: tokens })

        // 继续完成原来要执行的操作
        // 比如，在获取个人资料时，token 超时了，最终，在拿到最新的 token 后
        //      要继续获取个人资料
        // console.dir(error)
        // 可以通过 error.config 来拿到原来发送的请求的相关信息
        // 所以，要执行原来的操作，只需要将 error.config 重新请求一次即可
        // 注意：此处，一定要返回 Promise 的结果
        return http(error.config)
      } catch (e) {
        // 如果换取新 token 的过程中，代码出错了，一般就说明 refresh_token 失效了
        // 此时，就清空token然后返回登录页面
        // 注意：在直接分发 thunk action 时，会报类型错误
        // store.dispatch(logout())
        // 解决方式：先自己手动分发对象形式的 action 来实现退出
        store.dispatch({ type: 'login/logout' })
        // 手动清理本地的 token
        clearToken()

        Toast.show({
          content: '登录超时，请重新登录',
          duration: 1000,
          afterClose: () => {
            customHistory.replace('/login', {
              from: customHistory.location.pathname,
            })
          },
        })

        return Promise.reject(error)
      }
    }
    // == 无感刷新token=》401 end ==
    // 其它情况直接抛出错误
    return Promise.reject(error)
  }
)

export { http }
